//
//  PLVVodSkinPlayerController.m
//  PolyvVodSDK
//
//  Created by BqLin on 2017/10/28.
//  Copyright © 2017年 POLYV. All rights reserved.
//

#import "PLVVodSkinPlayerController.h"
#import "PLVVodPlayerSkin.h"
#import "PLVTimer.h"
#import <PLVVodSDK/PLVVodExam.h>
#import <MediaPlayer/MediaPlayer.h>
#import <PLVMarquee/PLVMarquee.h>
#import <MediaPlayer/MPVolumeView.h>
#import <React/RCTConvert.h>

//#import "PLVCastBusinessManager.h"

#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height

@interface PLVVodSkinPlayerController ()

@property (weak, nonatomic) IBOutlet UIView *skinView;


/// 播放刷新定时器
@property (nonatomic, strong) PLVTimer *playbackTimer;

/// 视频截图
@property (nonatomic, strong) UIImage *coverImage;

/// 滑动进度
@property (nonatomic, assign) NSTimeInterval scrubTime;

/// 修改系统音量
@property (nonatomic, strong) MPVolumeView *volumeView;

@end

@implementation PLVVodSkinPlayerController

#pragma mark - property

- (void)setVideo:(PLVVodVideo *)video quality:(PLVVodQuality)quality {
  // !!!: 这部分的功能的控制，由于与每次设置的 video 有关，因此必须在设置 PLVVodVideo 对象之前，或在这里设置。
  {
    
    // 记忆播放位置
    self.rememberLastPosition = NO;
  }
  
  [super setVideo:video quality:quality];
  if (!video.available) return;
  dispatch_async(dispatch_get_main_queue(), ^{
    [self setupPlaybackMode];
    // 设置控制中心播放信息
    self.coverImage = nil;
    [self setupPlaybackInfo];
  });
}

#pragma mark - view controller
- (void)destroyPlayer
{
  [super destroyPlayer];
  [self.playbackTimer cancel];
  self.playbackTimer = nil;
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)dealloc {
  RCTLog(@"-[%@ %@]",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
}

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view from its nib.
  
  self.automaticallyAdjustsScrollViewInsets = NO;
  
  [self setupSkin];
  
  [self addObserver];
  
  __weak typeof(self) weakSelf = self;
//  self.playbackTimer = [PLVTimer repeatWithInterval:0.2 repeatBlock:^{
//    dispatch_async(dispatch_get_main_queue(), ^{
//    });
//  }];
  
  // 配置手势
  self.gestureCallback = ^(PLVVodPlayerViewController *player, UIGestureRecognizer *recognizer, PLVVodGestureType gestureType) {
    [weakSelf handleGesture:recognizer gestureType:gestureType];
  };
  
  // 错误回调
  self.playerErrorHandler = ^(PLVVodPlayerViewController *player, NSError *error) {
    RCTLog(@"player error: %@", error);
    
  };
  
  // 恢复播放
  self.playbackRecoveryHandle = ^(PLVVodPlayerViewController *player) {
    
    // 应用层重试，减小sdk出错概率，降低风险
    [weakSelf setCurrentPlaybackTime:weakSelf.lastPosition];
    // 对于某些场景需要再次调用play函数才能播放
    [weakSelf play];
  };
}

- (void)viewDidLayoutSubviews {
  //RCTLog(@"layout guide: %f - %f", self.topLayoutGuide.length, self.bottomLayoutGuide.length);
}

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

- (void)setWrapperView:(RNTPolyvVod *)wrapperView {
  _wrapperView = wrapperView;
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  skin.wrapperView = wrapperView;
}

#pragma mark - private

- (void)setupSkin {
  PLVVodPlayerSkin *skin = [[PLVVodPlayerSkin alloc] initWithNibName:nil bundle:nil];
  __weak typeof(skin) _skin = skin;
  [self addChildViewController:skin];
  UIView *skinView = skin.view;
  [self.view addSubview:skinView];
  UIView *playerView = self.view;
  skinView.translatesAutoresizingMaskIntoConstraints = NO;
  NSDictionary *views = NSDictionaryOfVariableBindings(skinView, playerView);
  [playerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[skinView]|" options:0 metrics:nil views:views]];
  [playerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[skinView]|" options:0 metrics:nil views:views]];
  
  self.skinView = skinView;
  self.playerControl = skin;
  
  // 配置载入状态
  self.loadingHandler = ^(BOOL isLoading) {
    dispatch_async(dispatch_get_main_queue(), ^{
      isLoading ? [_skin.loadingIndicator startAnimating] : [_skin.loadingIndicator stopAnimating];
    });
  };
}

// 配置控制中心播放
- (void)setupPlaybackInfo {
  if (self.coverImage) {
    [self setupPlaybackInfoWithCover:self.coverImage];
    return;
  }
  __weak typeof(self) weakSelf = self;
  [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:self.video.snapshot] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (!data.length) return;
    weakSelf.coverImage = [UIImage imageWithData:data];
    [weakSelf setupPlaybackInfoWithCover:weakSelf.coverImage];
  }] resume];
}
- (void)setupPlaybackInfoWithCover:(UIImage *)cover {
  NSMutableDictionary *playbackInfo = [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo.mutableCopy;
  if (!playbackInfo.count) playbackInfo = [NSMutableDictionary dictionary];
  playbackInfo[MPMediaItemPropertyTitle] = self.video.title;
  playbackInfo[MPMediaItemPropertyPlaybackDuration] = @(self.video.duration);
  MPMediaItemArtwork *imageItem = [[MPMediaItemArtwork alloc] initWithImage:cover];
  playbackInfo[MPMediaItemPropertyArtwork] = imageItem;
  [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = playbackInfo;
}

// 设置播放模式
- (void)setupPlaybackMode {
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  [skin setUpPlaybackMode:self.video];
}


#pragma mark override
// 更新播放模式更新成功回调
- (void)playbackModeDidChange {
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  [skin updatePlayModeContainView:self.video];
}

- (void)updateAudioCoverAnimation:(BOOL)isPlaying {
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  [skin updateAudioCoverAnimation:isPlaying];
}

#pragma mark gesture

- (void)handleGesture:(UIGestureRecognizer *)recognizer gestureType:(PLVVodGestureType)gestureType {
  
  switch (gestureType) {
    case PLVVodGestureTypeTap:{
      PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
      [skin hideOrShowPlaybackControl];
    }break;
    case PLVVodGestureTypeDoubleTap:{
      [self playPauseAction:nil];
    }break;
    case PLVVodGestureTypeLeftSideDownPan:
    case PLVVodGestureTypeLeftSideUpPan:{
      [self changeBrightnessWithGesture:recognizer gestureType:gestureType];
    }break;
    case PLVVodGestureTypeRightSideDownPan:
    case PLVVodGestureTypeRightSideUpPan:{
      [self changeVolumeWithGesture:recognizer gestureType:gestureType];
    }break;
    case PLVVodGestureTypeLeftPan:
    case PLVVodGestureTypeRightPan:{
      [self changeProgressWithGesture:recognizer gestureType:gestureType];
    }break;
    default:{}break;
  }
}

- (void)changeBrightnessWithGesture:(UIGestureRecognizer *)recognizer gestureType:(PLVVodGestureType)gestureType {
  UIPanGestureRecognizer *pan = nil;
  if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
    pan = (UIPanGestureRecognizer *)recognizer;
  } else {
    return;
  }
  
  // 手势所在视图
  UIView *gestureView = pan.view;
  // 速率
  CGPoint veloctyPoint = [pan velocityInView:gestureView];
  // 皮肤
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  
  switch (pan.state) {
    case UIGestureRecognizerStateBegan: {
      [skin showGestureIndicator];
    } break;
    case UIGestureRecognizerStateChanged: {
      [UIScreen mainScreen].brightness -= veloctyPoint.y/10000;
      NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
      formatter.numberStyle = NSNumberFormatterPercentStyle;
      NSString *text = [formatter stringFromNumber:@([UIScreen mainScreen].brightness)];
      skin.gestureIndicatorView.type = PLVVodGestureIndicatorTypeBrightness;
      skin.gestureIndicatorView.text = text;
    } break;
    case UIGestureRecognizerStateEnded: {
      [skin hideGestureIndicator];
    } break;
    default: {} break;
  }
}

- (void)changeVolumeWithGesture:(UIGestureRecognizer *)recognizer gestureType:(PLVVodGestureType)gestureType {
  UIPanGestureRecognizer *pan = nil;
  if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
    pan = (UIPanGestureRecognizer *)recognizer;
  } else {
    return;
  }
  
  // 手势所在视图
  UIView *gestureView = pan.view;
  // 速率
  CGPoint veloctyPoint = [pan velocityInView:gestureView];
  // 皮肤
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  
  BOOL isSystemVolume = YES;
  if (isSystemVolume){
    // 系统音量调节
    switch (pan.state) {
      case UIGestureRecognizerStateBegan: {
      } break;
      case UIGestureRecognizerStateChanged: {
        self.playbackVolume -= veloctyPoint.y/10000;
        
        [self changeVolume:self.playbackVolume];
      } break;
      case UIGestureRecognizerStateEnded: {
      } break;
      default: {} break;
    }
  }
  else{
    // App 音量调节
    switch (pan.state) {
      case UIGestureRecognizerStateBegan: {
        [skin showGestureIndicator];
      } break;
      case UIGestureRecognizerStateChanged: {
        self.playbackVolume -= veloctyPoint.y/10000;
        
        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        formatter.numberStyle = NSNumberFormatterPercentStyle;
        NSString *text = [formatter stringFromNumber:@(self.playbackVolume)];
        skin.gestureIndicatorView.type = PLVVodGestureIndicatorTypeVolume;
        skin.gestureIndicatorView.text = text;
      } break;
      case UIGestureRecognizerStateEnded: {
        [skin hideGestureIndicator];
      } break;
      default: {} break;
    }
  }
}

- (void)changeVolume:(CGFloat)distance {
  if (self.volumeView == nil) {
    self.volumeView = [[MPVolumeView alloc] init];
    self.volumeView.showsVolumeSlider = YES;
  }
  
  for (UIView *v in self.volumeView.subviews) {
    if ([v.class.description isEqualToString:@"MPVolumeSlider"]) {
      UISlider *volumeSlider = (UISlider *)v;
      [volumeSlider setValue:distance];
      [volumeSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
      break;
    }
  }
}

- (void)changeProgressWithGesture:(UIGestureRecognizer *)recognizer gestureType:(PLVVodGestureType)gestureType {
  UIPanGestureRecognizer *pan = nil;
  if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
    pan = (UIPanGestureRecognizer *)recognizer;
  } else {
    return;
  }
  
  // 手势所在视图
  UIView *gestureView = pan.view;
  // 速率
  CGPoint veloctyPoint = [pan velocityInView:gestureView];
  // 皮肤
  PLVVodPlayerSkin *skin = (PLVVodPlayerSkin *)self.playerControl;
  
  switch (pan.state) {
    case UIGestureRecognizerStateBegan: { // 开始移动
      self.scrubTime = self.currentPlaybackTime;
      [skin showGestureIndicator];
    } break;
    case UIGestureRecognizerStateChanged: { // 正在移动
      self.scrubTime += veloctyPoint.x / 200;
      if (self.scrubTime > self.duration) { self.scrubTime = self.duration;}
      if (self.scrubTime < 0) { self.scrubTime = 0; }
      NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
      NSString *currentTimeString = [formatter stringFromTimeInterval:self.scrubTime];
      NSString *durationString = [formatter stringFromTimeInterval:self.duration];
      NSString *text = [NSString stringWithFormat:@"%@ / %@", currentTimeString, durationString];
      skin.gestureIndicatorView.text = text;
      if (gestureType == PLVVodGestureTypeLeftPan) {
        skin.gestureIndicatorView.type = PLVVodGestureIndicatorTypeProgressDown;
      } else {
        skin.gestureIndicatorView.type = PLVVodGestureIndicatorTypeProgressUp;
      }
    } break;
    case UIGestureRecognizerStateEnded: { // 移动停止
      self.currentPlaybackTime = self.scrubTime;
      self.scrubTime = 0;
      [skin hideGestureIndicator];
    } break;
    default: {} break;
  }
}



#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  if ([segue.destinationViewController isKindOfClass:[PLVVodPlayerSkin class]]) {
    self.playerControl = segue.destinationViewController;
  }
}

#pragma mark - observer

- (void)addObserver {
  // 接收远程事件
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(remoteControlEventDidReceive:) name:PLVVodRemoteControlEventDidReceiveNotification object:nil];
}


// 处理远程事件
- (void)remoteControlEventDidReceive:(NSNotification *)notification {
  UIEvent *event = notification.userInfo[PLVVodRemoteControlEventKey];
  if (event.type == UIEventTypeRemoteControl) {
    // 更新控制中心
    NSMutableDictionary *playbackInfo = [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo.mutableCopy;
    if (!playbackInfo.count)
      playbackInfo = [NSMutableDictionary dictionary];
    playbackInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(self.currentPlaybackTime);
    playbackInfo[MPNowPlayingInfoPropertyPlaybackRate] = @(self.playbackRate);
    playbackInfo[MPMediaItemPropertyPlaybackDuration] = @(self.duration);
    [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = playbackInfo;
    
    switch (event.subtype) {
      case UIEventSubtypeRemoteControlPause:{
        [self pause];
      }break;
      case UIEventSubtypeRemoteControlPlay:{
        [self play];
      }break;
      case UIEventSubtypeRemoteControlTogglePlayPause:{
        [self playPauseAction:nil];
      }break;
      case UIEventSubtypeRemoteControlPreviousTrack:{
        
      }break;
      case UIEventSubtypeRemoteControlNextTrack:{
        
      }break;
      case 5:{
        
      }break;
      default:{}break;
    }
  }
}


@end
